package com.ddf.norman.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ddf.norman.util.HashPasswordEncoder;
import com.ddf.norman.util.RegexUtils;
import com.ddf.norman.util.URLEncodeUtil;
import com.ddf.publics.entity.QQUserInfo;
import com.ddf.publics.entity.User;
import com.ddf.publics.entity.UserInfo;
import com.ddf.publics.service.LoginService;
import com.ddf.publics.service.QQService;
import com.ddf.publics.service.UserInfoService;
import com.ddf.publics.service.UserService;
import com.ddf.publics.tool.Constant;
import com.ddf.publics.utils.RedisUtil;
import com.ddf.publics.utils.VerificationCodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: UserController.java
 * @Description: 登陆注册控制器
 * @author: norman
 * @date:  2020-06-09 20:17
 * @version V2.4
 */
@Controller
public class UserController {
    //注入服务层
    @Autowired
    private UserService userService;
    @Autowired
    private LoginService loginService;
    @Autowired
    private UserInfoService userInfoService;

    //注入redis工具类
    @Autowired
    private RedisUtil redisUtil;
    //注入密码加盐工具类
    @Autowired
    private HashPasswordEncoder hashPasswordEncoder;
    @Autowired
    private VerificationCodeUtil verificationCodeUtil;

    //QQ登录的信息
    @Value("${qq.appId}")
    private String appId;
    @Value("${qq.secretKey}")
    private String secretKey;
    @Value("${qq.redirect_url}")
    private String redirect_url;

    /**
     * @description 请求登录页面
     * @author norman
     * @date 2020/7/5 19:13
     * @params [model]
     * @return java.lang.String
     */
    @GetMapping(value = "/login")
    public String login(Model model){
        StringBuffer url = new StringBuffer();
        url.append("https://graph.qq.com/oauth2.0/authorize");
        url.append("?response_type=code");
        url.append("&client_id=" + appId);
        url.append("&redirect_uri=" + URLEncodeUtil.getURLEncoderString(redirect_url));
        url.append("&state=200");
        model.addAttribute("url",url);
        return "login";
    }

    /**
     * @description 获取用户名
     * @author norman
     * @date 2020/7/3 10:41
     * @params [principal]
     * @return java.lang.String
     */
    @ResponseBody
    @RequestMapping("/getUserName")
    public String getUserName(Principal principal) {
        if (principal.getName() != null) {
            User user = loginService.queryByPhone(principal.getName());
            return user.getNickName();
        }
        return "null";
    }

    /**
     * @description 请求注册页面
     * @author norman
     * @date 2020/6/9 20:17
     * @params []
     * @return java.lang.String
     */
    @GetMapping(value = "/register")
    public String register(){
        return "register";
    }

    /**
     * @description 发送注册短信验证码
     * @author norman
     * @date 2020/6/11 8:14
     * @params [phone]
     * @return boolean
     */
    @ResponseBody
    @PostMapping(value = "/sendRegisterVerify")
    public String sendVerify(String phone){
        if (!RegexUtils.checkPhone(phone)) {
            return "请输入正确的手机号";
        }
        if (loginService.queryByPhone(phone) != null) {
            return "手机号已注册";
        }

        boolean checkPhone = RegexUtils.checkPhone(phone);
        if (checkPhone){
            String code = String.valueOf((int)((Math.random()*9+1)*100000));
            System.out.println("code = " + code);
            String message = verificationCodeUtil.sendCode(phone, VerificationCodeUtil.ALI_TEMPLATE_REGISTER,code);
            if ("OK".equals(message)) {
                redisUtil.set("regCode:" + phone,code,5 * 60);
            } else {
                System.out.println("message = " + message);
                return "服务器繁忙";
            }
        }
        return "success";
    }

    /**
     * @description 用户注册的请求
     * @author norman
     * @date 2020/6/10 14:39
     * @params [user, verify]
     * @return java.lang.String
     */
    @ResponseBody
    @PostMapping(value = "/userRegister")
    public String userRegister(User user, String verify){
        if (verify != null && user != null){
            if (loginService.queryByPhone(user.getPhone()) != null) {
                return "该手机号已注册";
            }

            if (user.getInviteNum() != null && !"".equals(user.getInviteNum()) && loginService.queryByPhone(user.getInviteNum()) == null) {
                return "该推荐人未注册";
            }

            Object code = redisUtil.get("regCode:" + user.getPhone());
            if (code == null || !verify.equals(code)) {
                return "验证码错误";
            }
            user.setFace("/img/defaultFace.png");
            user.setRegisterTime(new Date());
            user.setResiduePoint(0);
            user.setCredit(0);
            user.setPassword(hashPasswordEncoder.encode(user.getPassword()));

            UserInfo userInfo = new UserInfo();
            user = userService.insert(user);

            userInfo.setUId(user.getId());
            userInfo.setMoney(0f);
            userInfo.setStayRepay(0f);
            userInfo.setCountRepay(0f);
            userInfoService.insert(userInfo);
            return "success";
        }
        return "注册失败 参数错误";
    }

    /**
     * @description 请求找回密码页面
     * @author norman
     * @date 2020/6/15 10:48
     * @params []
     * @return java.lang.String
     */
    @GetMapping(value = "/forgot")
    public String forgot(){
        return "forgot";
    }

    /**
     * @description 发送修改密码的验证码
     * @author norman
     * @date 2020/6/16 14:24
     * @params [phone]
     * @return java.lang.String
     */
    @ResponseBody
    @PostMapping(value = "/sendForgotVerify")
    public String sendForgotVerify(String phone){
        if (!RegexUtils.checkPhone(phone)) {
            return "请输入正确的手机号";
        }
        if (loginService.queryByPhone(phone) == null) {
            return "手机号未注册";
        }

        boolean checkPhone = RegexUtils.checkPhone(phone);
        if (checkPhone){
            String code = String.valueOf((int)((Math.random()*9+1)*100000));
            System.out.println("code = " + code);
            String message = verificationCodeUtil.sendCode(phone,VerificationCodeUtil.ALI_TEMPLATE_FORGOT,code);
            if ("OK".equals(message)) {
                redisUtil.set("forgotCode:" + phone, code,5 * 60);
            } else {
                System.out.println("message = " + message);
                return "服务器繁忙";
            }
        }
        return "success";
    }

    /**
     * @description 修改密码
     * @author norman
     * @date 2020/6/16 14:25
     * @params [phone, password, verify]
     * @return java.lang.String
     */
    @ResponseBody
    @PostMapping(value = "/userForgot")
    public String userForgot(String phone, String password, String verify) {
        Object code = redisUtil.get("forgotCode:" + phone);
        System.out.println("code = " + code);
        if (code == null || !verify.equals(code)) {
            return "验证码错误";
        }
        User user = loginService.queryByPhone(phone);
        user.setPassword(hashPasswordEncoder.encode(password));
        User newUser = userService.update(user);
        if (newUser == null) {
            return "服务器繁忙，请稍后再试";
        }
        return "success";
    }
}
